package cc.rboot.chain.core;

import cc.rboot._core.holder.AppContextHolder;
import org.springframework.core.annotation.Order;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public abstract class AbstractChainManager<T> implements IChainManager<T> {

    private List<IChain<T>> chains;

    @Resource
    AppContextHolder appContextHolder;

    @PostConstruct
    public void construct() {
        Class<? extends IChain<T>> abstractChain = this.init();
        Map<String, ? extends IChain<T>> map = appContextHolder.getBeansOfType(abstractChain);
        chains = map.values().stream().sorted((o1, o2) -> {
            Order o1Order = o1.getClass().getAnnotation(Order.class);
            Order o2Order = o2.getClass().getAnnotation(Order.class);
            if (o1Order == null && o2Order == null) {
                return 0; // 一样大
            } else if (o1Order == null) {
                return 1; // o2大
            } else if (o2Order == null) {
                return -1; // o1大
            } else if (o1Order.value() > o2Order.value()) {
                return 1;
            } else if (o1Order.value() < o2Order.value()) {
                return -1;
            } else {
                return 0;
            }
        }).collect(Collectors.toList());
    }

    @Override
    public void execute(T request) {
        chains.forEach((chain) -> {
            chain.execute(request);
        });
    }
}
